"use strict";

//**********************************************
// Sprite class                                
//**********************************************
function Sprite(args) { Copy(this, args); }
Sprite.prototype = new GameObject();
Sprite.prototype._class = 'Sprite';
Sprite.prototype.x = 0;
Sprite.prototype.y = 0;
Sprite.prototype.z = 0;
Sprite.prototype.textalign = 'left';
Sprite.prototype.events = {};
Sprite.prototype.backcolor = "#555500";
Sprite.prototype.forecolor = "#000000";
Sprite.prototype.pathcolor = "rgba(255, 255, 0, .7)";
Sprite.prototype.moverandom = false;
Sprite.prototype.DrawMe = function (g) { }
Sprite.prototype.Tick = function () { }
Sprite.prototype.GetPos = function ()
{
    var px = Math.floor(this.x / engine.tilesize);
    var py = Math.floor(this.y / engine.tilesize);
    return { x: px, y: py };
}

//**********************************************
// ImageSprite class
//**********************************************
function ImageSprite(args)
{
    Copy(this, args);
    if (this.isplayer)
        engine.player = this;
}
ImageSprite.prototype = new Sprite();
ImageSprite.prototype._class = 'ImageSprite';
ImageSprite.prototype.effects = [];
ImageSprite.prototype.src = null;
ImageSprite.prototype.animations = null;
ImageSprite.prototype._frame = 0;
ImageSprite.prototype._animnexttime = 0;
ImageSprite.prototype._animfps = 10;
ImageSprite.prototype.Tick = function ()
{
    this.TickMovement();
    this.TickFrame();
    if (this.moverandom == true && (this.path == null || this.path.length == 0))
    {
        var x = Math.floor(Math.random() * (level.tilemap[0].length));
        var y = Math.floor(Math.random() * (level.tilemap.length));
        if (tilemap.walkmap[x][y] == 0)
            engine.MoveTo(this, x * engine.tilesize, y * engine.tilesize);
    }
}
ImageSprite.prototype.SetPath = function (px, py, newpx, newpy)
{
    pathing.DisposePath(this.path);
    this.path = pathing.GetPath(px, py, newpx, newpy, this.pathcolor);
}
ImageSprite.prototype.TickMovement = function ()
{
    if (this.path == null)
        return;
    var pos = this.GetPos();
    var path = pathing.PeekPath(this.path);
    if (path == null)
    {
        this.path == null;
        return;
    }
    var movesprite = true;
    var finalpos = { x: path.x * engine.tilesize, y: path.y * engine.tilesize };
    if (Math.pow(this.x - finalpos.x, 2) + Math.pow(this.y - finalpos.y, 2) < 16)
    {
        this.x = finalpos.x;
        this.y = finalpos.y;
        if (pathing.PopPath(this.path) == null)
        {
            this.animation = this.animation.replace('walk', 'stand');
        }
    } else
    {
        var adj = { x: 4, y: 3 };
        if (finalpos.x > this.x)
        {
            this.animation = 'walkright';
            this.x += adj.x;
        }
        else if (finalpos.x < this.x)
        {
            this.animation = 'walkleft';
            this.x -= adj.x;
        }
        else if (finalpos.y > this.y)
        {
            this.animation = 'walkdown';
            this.y += adj.y;
        }
        else if (finalpos.y < this.y)
        {
            this.animation = 'walkup';
            this.y -= adj.y;
        }
    }
}

ImageSprite.prototype.TickFrame = function ()
{
    if (!this.animations)
        return;
    if (engine.now > this._animnexttime)
    {
        this._animnexttime = engine.now + 1000 / this._animfps;
        this._frame += 1;
        if (this._frame >= this.animations[this.animation].length)
            this._frame = 0;
    }
}
ImageSprite.prototype.DrawMe = function (g)
{
    var src = library.tiles[this.src];
    var img = src.image;
    if (!img || !img.complete || img.width == 0 || img.height == 0)
    {
        return;
    }
    var offset = { x: -engine.camera.x, y: -engine.camera.y };
    var temp = null;
    var index = 0;
    if (this.animations)
        index = this.animations[this.animation][Math.min(this._frame, this.animations[this.animation].length - 1)];
    else
        index = this._frame;
    var t = src.map[index];
    var x = t[0], y = t[1], w = t[2], h = t[3], ox = t[4], oy = t[5];
    try
    {
        g.drawImage(img, x, y, w, h, offset.x + this.x - ox, offset.y + this.y - oy, w, h);
    }
    catch (ex)
    {
        log('Error when drawing ' + this.name + ' - ' + ex.message + '\n' +
            'src=' + src.filename + ', src.image = ' + this.src.image + ', tiles=' + tiles + ', img = ' + img + ', ' +
            't = ' + t + '\n' + ex.toString());
    }
}

//**********************************************
// BallSprite class
//**********************************************
function BallSprite(args) { Copy(this, args); }
BallSprite.prototype = new Sprite();
BallSprite.prototype._class = 'BallSprite';
BallSprite.prototype.adjx = 1;
BallSprite.prototype.adjy = 1;
BallSprite.prototype.Tick = function ()
{
    this.x += this.adjx;
    this.y += this.adjy;
    var maxx = engine.screenwidth - this.w;
    var maxy = engine.screenheight - this.h;
    if (this.x > maxx)
    {
        this.adjx *= -1;
        this.x = Math.min(this.x, maxx);
    }
    if (this.x < 0)
    {
        this.adjx *= -1;
        this.x = Math.max(this.x, 0);
    }
    if (this.y > maxy)
    {
        this.adjy *= -1;
        this.y = Math.min(this.y, maxy);
    }
    if (this.y < 0)
    {
        this.adjy *= -1;
        this.y = Math.max(this.y, 0);
    }
}

//**********************************************
// CursorSprite class 
//**********************************************
function CursorSprite(args) { Copy(this, args); }
CursorSprite.prototype = new ImageSprite();
CursorSprite.prototype._class = "CursorSprite";
CursorSprite.prototype.Tick = function ()
{
    this.x = engine.mousepos.x - engine.camera.x;
    this.y = engine.mousepos.y - engine.camera.y;
    this.TickFrame();
}

//**********************************************
// TextSprite class
//**********************************************
function TextSprite(args) { Copy(this, args); }
TextSprite.prototype = new Sprite();
TextSprite.prototype._class = "TextSprite";
TextSprite.prototype.text = "TextSprite";
TextSprite.prototype.textalign = 'left';
TextSprite.prototype.multiline = false;
TextSprite.prototype.static = false;
TextSprite.prototype.textbaseline = 'top';
TextSprite.prototype.fontname = "F8bitoperatorJVE_12";
TextSprite.prototype.backcolor = "#EEEEEE";
TextSprite.prototype.forecolor = "rgba(255, 255, 200, .9)";
TextSprite.prototype.DrawMe = function (g)
{
    var lines = null;
    if (this.multiline == true)
        lines = this.text;
    else
        lines = [this.text];
    for (var i = 0; i < lines.length; i++)
    {
        var metrics = font.measureFont(this.fontname, lines[i]);
        var adjx = 0, adjy = 0;
        if (this.textalign == 'center')
            adjx = -Math.round(metrics.width / 2);
        else if (this.textalign == 'right')
            adjx = -metrics.width;
        else if (this.textalign == 'middle')
            adjy = -Math.round(metrics.height / 2);
        else if (this.textalign == 'bottom')
            adjy = -metrics.height;
        // The UI layer 'floats' over the top.
        if (!this.static)
        {
            adjx -= engine.camera.x;
            adjy -= engine.camera.y;
        }
        font.drawText(this.fontname, g, this.x + adjx, this.y + adjy, lines[i], this.forecolor);
    }
}
TextSprite.prototype.Tick = function ()
{
    if ('fps' in this.events)
        this.text = engine.fps.toString() + ' FPS';
    if ('xy' in this.events)
        this.text = (engine.camera.x + engine.mousepos.x) + ', ' + (engine.camera.y + engine.mousepos.y);
    if ('keypress' in this.events)
    {
        if (this.multiline == false)
            this.text = engine.GetLastLine();
        else
            this.text = engine.GetAllLines();
    }
    if ('speed' in this.events)
        this.text = 'Engine speed: ' + engine.speed.toString();
    if ('camera' in this.events)
        this.text = 'Camera: ' + engine.camera.x + ',' + engine.camera.y;
}
